home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Science
/
RLaB
/
rlib
/
plplot.r
< prev
next >
Wrap
Text File
|
1994-04-25
|
35KB
|
1,463 lines
//-------------------------------------------------------------------//
// plplot.r
// Syntax: pstart ( NCOL, NROW, DEVICE )
// pwin ( NWIN )
// showpwin ( )
// pclose ( )
// pend ( )
// plot ( DATA )
// plhist ( DATA )
// xlabel ( XLABEL )
// ylabel ( YLABEL )
// ptitle ( PTITLE )
// plimits ( XMIN, XMAX, YMIN, YMAX, ZMIN, ZMAX )
// plgrid ( GRID_STY_X, GRID_STY_Y )
// plgrid3 ( GRID_STY_X, GRID_STY_Y, GRID_STY_Z )
// plaxis ( X_STR, Y_STR )
// plstyle ( PSTYLE )
// plot3 ( L3D )
// zlabel ( ZLABEL )
// plalt ( ALT )
// plaz ( AZ )
// plfont ( FONT )
// plwid ( WIDTH )
// plptex ( TEXT, X, Y, DX, DY, JUST )
// plprint ( FILENM, DEVICE )
// replot ( )
// Description:
// These function define a user interface to the PLPLOT grpahics
// library. The PLPLOT graphics library can produce output on
// X-windows, DOS, OS/2, Amiga, Tektronicks, postscipt, and other
// output devices.
// The plot interface operation is based upon two important
// concepts: the current plot-window, and the current sub-plot.
// The current plot-window is a valid concept only if selected
// output device supports multiple windows (X-windows for
// example).
// The current sub-plot should be available for all devices,
// since sub-plots are individual plots that co-exist on the same
// page, or display.
// Invoking pstart() will create a plot-window. The newly created
// plot-window will be the current plot-window. If more than one
// plot-window has been created, then the current window can be
// selected with the pwin() function. The current plot-window can
// be closed with pclose(). All of the plot-windows can be closed
// with pend().
// Each plot-window can be divided up into more than 1 sub-plot
// (the default). The number and arrangement of the sub-plots is
// specified by the user when pstart() is invoked. All plot
// manipulation functions, such as ptyle(), pgrid(), xlabel(),
// etc... work on the current sub-plot. When plot() is used the
// current sub-plot is created, and the current sub-plot is
// incremented. the sub-plots are incremented to the right, and
// down (the same way you read a English language book).
// pstart ( NCOL, NROW, DEVICE )
// Create a plot-window. The newly created plot-windown
// becomes the current plot-window with NCOLxNROW
// sub-plots. DEVICE specifies the output device type. If
// DEVICE is not specified, then the user is provided
// with a menu of options. All arguments are optional.
// This function MUST be used before any plotting can
// occur.
// pwin ( N )
// Switch the current plot-window to plot-window N.
// pclose ( )
// Close the current plot-window. The new current
// plot-window is the remaining plot-window with the
// lowest tag value.
// pend ( )
// End the current plotting session. Closes all
// plot-windows.
// plot ( DATA )
// Plot DATA in the current sub-plot in the current
// plot-window. DATA can consist of either a matrix, in
// which case the columns are plotted against the 1st
// column. DATA can also consist of a list, in which case
// each matrix in the list is plotted (this is a good way
// to plot data with different scales).
// plhist ( DATA , NBIN )
// Plot a histogram of the data in DATA. DATA can be a
// N-column matrix. The columns of DATA are plotted in
// histogram fashion. An optional second argument, NBIN
// specifies the number of bins to separate the data
// into. If NBIN is not specifies the default is 10.
// xlabel ( XLABEL )
// Set the x-axis label for the current sub-plot in the
// current plot-window. If xlabel is used without any
// arguments, then the x-axis label is set to the
// null-string.
// ylabel ( YLABEL )
// Set the y-axis label for the current sub-plot in the
// current plot-window.
// ptitle ( PTITLE )
// Set the title for the current sub-plot in the current
// plot-window.
// plimits ( XMIN, XMAX, YMIN, YMAX, ZMIN, ZMAX )
// Set the scale limits of the current sub-plot in the
// current plot-window. If any of the arguments are
// omitted, then the corresponding scale limit is
// determined from the data.
// plgrid ( GRID_STY_X, GRID_STY_Y )
// Set the grid type for the current sub-plot in the
// curent plot-window. The grid type is specified by a
// string. The possible elements of the string are
// described below. The string can include any
// combination of the following letters (lower case) in
// any order. If plgrid is called without any
// arguments, the defaults are reset.
// a Draws axis, X-axis is horizontal line
// (at y=0), and Y-axis is vertical line (at x=0).
// b Draws bottom (X) or left (Y) edge of frame.
// c Draws top (X) or right (Y) edge of frame.
// g Draws a grid at the major tick interval.
// i Inverts tick marks, so they are drawn
// outwards, rather than inwards.
// l Scales axis logarithmithecally.
// m Writes numeric labels at major tick intervals
// in the unconventional location
// (above box for X, right of box for Y).
// n Writes numeric labels at major tick intervals
// in the conventional location
// (below box for X, left of box for Y).
// s Enables subticks between major ticks, only
// valid if "t" is also specified.
// t Draws major ticks.
// Example - Set X and Y logarithmic scales:
// plgrid ( "bcgnstl", "bcgnstlv")
// plaxis ( X_STR, Y_STR )
// An friendlier interface to the axis styles. Currently
// plaxis only supports the default and a predefined
// logarithmic axis styles. X_STR and/or Y_STR can be
// either "log" or "", or omitted. If the string "log" is
// used for either argument, then that axis is scaled
// logarithmically. Otherwise, the default axis style is
// used .
// Example: plaxis ("log", "log")
// plgrid3 ( GRID_STY_X, GRID_STY_Y, GRID_STY_Z )
// Set the grid type for the current sub-plot in the
// curent plot-window. The grid type is specified by a
// string. The possible elements of the string are
// described below. The string can include any
// combination of the following letters (lower case) in
// any order. If plgrid3 is called without any
// arguments, the defaults are reset.
// b Draws axis at base, at height
// (z=zmin). This character must be specified
// in order to use any of the other options.
// i Inverts tick marks, so they are drawn
// downwards, rather than upwards.
// l Scale axis logarithmically.
// n Writes numeric labels at major tick intervals.
// s Enables subticks between major ticks, only
// valid if "t" is also specified.
// t Draws major ticks.
// u If this is specified, the text label for the
// axis is written under the axis.
// plstyle ( STYLE )
// Plstyle controls the line-style for 2-dimensional
// graphs. STYLE can be: "line", "point", and
// "line-point". In the future plstyle will accept a
// vector of style strings so that different lines can
// have different styles within the same graph.
// plot3 ( L1, L2, L3 )
// Plot3 creates a 3-dimensional surface plot from the
// data in lists L1, L2, L3 (L2 and L3 are optional). The
// list must contain elemenst `x', `y', and `z'. the z
// element is a rectangular matrix that is a function of
// x and y (z[i;j] = f(x[i],y[j])). Up to 3 lists, or
// surface plots can be created on the same sub-plot.
// zlabel ( ZLABEL )
// Set the z-axis label for the current sub-plot in the
// current plot-window. If zlabel is used without any
// arguments, then the z-axis label is set to the
// null-string.
// plalt ( ALT )
// Set the "altitude" for the current sub-plot in the
// current plot-window. The viewing altitude in degrees
// above the XY plane. Only affects 3D plots.
// plaz ( AZ )
// Set the "azimuth" for the current sub-plot in the
// current plot-window. Azimuth represents the viewing
// angle in degrees. When AZ=0, the observer is looking
// face onto the ZX plane, and as AZ is increased, the
// observer moves clockwise around the box when viewed
// from above the XY plane. Only affects 3D plots.
// plfont ( FONT )
// Change to font-style FONT.
// FONT 1: Normal (simplest and fastest)
// 2: Roman font
// 3: Italic font
// 4: Script font
// plwid ( WIDTH )
// Change the pen width to WIDTH. The result is device
// dependent. For some devices, such as postscipt, WIDTH
// must be > 0 and <= 10.
// plptex ( TEXT, X , Y , DX , DY , JUST )
// Place TEXT in the plot window.
// X: Specify the X coordinate for text placement.
// Y: Specify the Y coordinate for text placement.
// DX: X + DX specifies the X orientation of the text.
// DY: Y + DY specifies the Y orientation of the text.
// JUST: Specifies the position of the string relative to
// its reference point. If JUST=0, the reference point is
// at the left and if JUST=1 it is at the right of the
// string. Other values of JUST give intermediate
// justifications. Since plptex uses the plot-data
// coordinates for text placement, plptex must be called
// AFTER the plot is created.
// plprint ( FILENM , DEVICE )
// Print the contents of the current plot-window to the
// PLPLOT device identified by the string DEVICE (the
// default is black and white Postscript if DEVICE is
// omitted). Options are:
// "ps" Postscript (default)
// "psc" Color Postscript
// "xfig" Xfig file format
// "plmeta" Plplot meta-file
// "ljii" HP LaserJet II
// replot ( )
// Re-draws the current plot-window.
//-------------------------------------------------------------------//
#
# New plot.r for use with PLPLOT library.
#
static (WIN) # The static plot window structure
static (P) # The active/current plot window
static (create_plot_object)
static (check_plot_object)
static (xy_scales)
static (xyz_scales)
static (list_scales)
static (hist_scales)
static (plot_matrix)
static (plot_list)
static (check_3d_list)
static (find_char)
#
# Defaults
#
static (grid_x_default, grid_y_default)
static (grid_3x_default, grid_3y_default, grid_3z_default)
grid_x_default = "bcgnst";
grid_y_default = "bcgnstv";
grid_3x_default = "bnstu";
grid_3y_default = "bnstu";
grid_3z_default = "bcdmnstuv";
#
# Create the default plot-object.
# Initialize to all the default values
#
WIN = <<>>; # Create the plot-object list
create_plot_object = function ( N, nx, ny )
{
local (i, j, pobj)
if (!exist (N)) { N = 0; }
pobj = <<>>;
pobj.subplot = 0; # The current subplot no.
pobj.nplot = nx*ny; # Total no. of plots on window
pobj.fontld = 0; # Loaded extended fonts?
for (i in 1:(nx*ny))
{
pobj.style[i] = "line"; # The type/style of plot to draw
pobj.pstyle[i] = 1; # The point-style
pobj.nbin[i] = inf(); # The number of bins for a histogram
pobj.width[i] = 1; # The pen width for current plot
pobj.font[i] = 1; # The current font
pobj.xlabel[i] = "";
pobj.ylabel[i] = "";
pobj.zlabel[i] = "";
pobj.title[i] = "";
pobj.orientation[i] = "portrait";
pobj.gridx[i] = grid_x_default; # Plot axes style, 2D-X
pobj.gridy[i] = grid_y_default; # Plot axes style, 2D-Y
pobj.grid3x[i] = grid_3x_default; # Plot axes style, 3D-X
pobj.grid3y[i] = grid_3y_default; # Plot axes style, 3D-Y
pobj.grid3z[i] = grid_3z_default; # Plot axes style, 3D-Z
pobj.aspect[i] = 0; # Plot aspect style
pobj.alt[i] = 60;
pobj.az[i] = 45;
pobj.xmin[i] = inf();
pobj.xmax[i] = inf();
pobj.ymin[i] = inf();
pobj.ymax[i] = inf();
pobj.zmin[i] = inf();
pobj.zmax[i] = inf();
for (j in 1:14) { pobj.color[i;j] = j; }
for (j in 1:8) { pobj.lstyle[i;j] = j; }
}
#
# Save and return the newly generated plot-object
#
WIN.[N] = pobj;
return WIN.[N];
};
#
# Check to make sure a plot-object exists. If one
# does not exist, create it.
#
check_plot_object = function ()
{
if (length (WIN) == 0)
{
pstart();
return 0;
}
return 1;
};
#
# Set the current plot window
# Default value = 0
#
pwin = function ( N )
{
check_plot_object ();
if (!exist (N)) { N = 0; }
# Check to make sure N is valid
for (i in members (WIN))
{
if (N == strtod (i))
{
_plsstrm (N);
return P = N;
}
}
printf ("pwin: invalid argument, N = %i\n", N);
printf (" valid values are:\n");
WIN?
};
showpwin = function ()
{
check_plot_object ();
printf ("Curren plot-window is: %i\n", P);
printf ("Available plot windows are:\n");
WIN?
};
#
# Set/start/select the plot device
#
pstart = function ( nx, ny, dev )
{
if (!exist (nx)) { nx = 1; }
if (!exist (ny)) { ny = 1; }
if (!exist (dev)) { dev = "?"; }
# Create the plot-object
# First, figure out the index
if (!exist (P))
{
P = 0;
else
P = P + 1;
}
create_plot_object (P, nx, ny);
_plsstrm (P);
# Default window size for X
_plspage (0, 0, 400, 300, 200, 200);
# Start up the plot-window
_plstart (dev, nx, ny);
_plwid (8);
# Turn between plot pause off
_plspause (0);
_pltext ();
return P;
};
#
# Close a plot device. We must destroy the current plot-object
# And switch the output stream back to the default.
#
pclose = function ()
{
local (n)
if (size (WIN) > 1)
{
clear (WIN.[P]);
_plend1 ();
_plsstrm (strtod (members (WIN)[1]));
P = strtod (members (WIN)[1]);
else
if (exist (WIN.[P])) { clear (WIN.[P]); }
_plend1 ();
}
};
#
# Close ALL the plot-windows
#
pend = function ()
{
_plend ();
if (exist (WIN)) { clear (WIN); }
if (exist (P)) { clear (P); }
WIN = <<>>;
};
##############################################################################
#
# Plot the columns of a matrix (X-Y plot).
#
##############################################################################
plot = function ( data )
{
local (hscale, xmin, xmax, ymin, ymax, i, p)
check_plot_object ();
p = mod (WIN.[P].subplot, WIN.[P].nplot) + 1; # The current index
#
# Draw the graph
# Step through the matrix plotting
# each column versus the 1st
#
if (class (data) == "num")
{
_plgra ();
_plcol (1);
_pllsty (1);
_plfont (WIN.[P].font[p]);
_plwid (WIN.[P].width[p]);
xy_scales ( real(data), p, xmin, xmax, ymin, ymax );
_pladv (0);
_plvsta ();
_plwind (xmin, xmax, ymin, ymax);
_plbox (WIN.[P].gridx[p], 0, 0, WIN.[P].gridy[p], 0, 0);
if (plot_matrix ( data, p, 0 ) < 0) { return -1; }
else if (class (data) == "list") {
_plgra ();
_plcol (1);
_pllsty (1);
_plfont (WIN.[P].font[p]);
_plwid (WIN.[P].width[p]);
list_scales ( data , p, xmin, xmax, ymin, ymax );
_pladv (0);
_plvsta ();
_plwind (xmin, xmax, ymin, ymax);
_plbox (WIN.[P].gridx[p], 0, 0, WIN.[P].gridy[p], 0, 0);
if (plot_list ( data, p ) < 0) { return -1; }
else
error ("plot: un-acceptable argument");
}}
_plcol (1);
_pllab (WIN.[P].xlabel[p], WIN.[P].ylabel[p], WIN.[P].title[p]);
_plflush ();
_pltext ();
#
# Increment the plot no. so that next time
# we use the correct settings.
#
WIN.[P].subplot = WIN.[P].subplot + 1;
return P;
};
##############################################################################
#
# Plot a 3-Dimensional graph. The data is composed in a list, with
# elements `x', `y', and `z'. x and y are single-dimension arrays
# (row or column matrices), and z is a two-dimensional array. The
# array z, is a function of x and y: z = f(x,y). Thus, the values in
# the array x can be thought of a "row-labels", and the values of y
# can be thought of as "column-lables" for the 2-dimensioal array z.
#
# At present plot3 can plot 3 distinct lists. Each list may have
# different X, Y, and Z scales.
#
##############################################################################
plot3 = function ( L31, L32, L33 )
{
local (p, xmin, xmax, ymin, ymax, zmin, zmax, basex, basey, height, ...
xmin2d, xmax2d, ymin2d, ymax2d, alt, az, ...
Xmin, Xmax, Ymin, Ymax, Zmin, Zmax)
check_plot_object ();
#
# 1st check list contents
#
if (exist (L31)) { check_3d_list (L31); }
if (exist (L32)) { check_3d_list (L32); }
if (exist (L33)) { check_3d_list (L33); }
p = mod (WIN.[P].subplot, WIN.[P].nplot) + 1; # The current index
#
# Figure out the scale limits.
# Needs improvement!
#
xmin = xmax = ymin = ymax = zmin = zmax = 0;
if (exist (L31))
{
xyz_scales (L31, p, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
if (Xmin < xmin) { xmin = Xmin; } if (Xmax > xmax) { xmax = Xmax; }
if (Ymin < ymin) { ymin = Ymin; } if (Ymax > ymax) { ymax = Ymax; }
if (Zmin < zmin) { zmin = Zmin; } if (Zmax > zmax) { zmax = Zmax; }
}
if (exist (L32))
{
xyz_scales (L32, p, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
if (Xmin < xmin) { xmin = Xmin; } if (Xmax > xmax) { xmax = Xmax; }
if (Ymin < ymin) { ymin = Ymin; } if (Ymax > ymax) { ymax = Ymax; }
if (Zmin < zmin) { zmin = Zmin; } if (Zmax > zmax) { zmax = Zmax; }
}
if (exist (L33))
{
xyz_scales (L33, p, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
if (Xmin < xmin) { xmin = Xmin; } if (Xmax > xmax) { xmax = Xmax; }
if (Ymin < ymin) { ymin = Ymin; } if (Ymax > ymax) { ymax = Ymax; }
if (Zmin < zmin) { zmin = Zmin; } if (Zmax > zmax) { zmax = Zmax; }
}
_plgra ();
_plcol (1);
_pllsty (1);
_plfont (WIN.[P].font[p]);
_plwid (WIN.[P].width[p]);
basex = 2; basey = 2; height = 4;
xmin2d = -2.0; xmax2d = 2.0;
ymin2d = -2.5; ymax2d = 5.0;
_plenv (xmin2d, xmax2d, ymin2d, ymax2d, 0, -2);
_plw3d (basex, basey, height, xmin, xmax, ymin, ymax, ...
zmin, zmax, WIN.[P].alt[p], WIN.[P].az[p]);
_plbox3 (WIN.[P].grid3x[p], WIN.[P].xlabel[p], 0, 0, ...
WIN.[P].grid3y[p], WIN.[P].ylabel[p], 0, 0, ...
WIN.[P].grid3z[p], WIN.[P].zlabel[p], 0, 0);
_plmtex ("t", 1.0, 0.5, 0.5, WIN.[P].title[p]);
if (exist (L31))
{
_plcol (2);
_plot3d (real(L31.x), real(L31.y), real(L31.z), ...
L31.x.n, L31.y.n, 3, 0);
}
if (exist (L32))
{
_plcol (3);
_pllsty (2);
_plot3d (real(L32.x), real(L32.y), real(L32.z), ...
L32.x.n, L32.y.n, 3, 0);
}
if (exist (L33))
{
_plcol (4);
_pllsty (3);
_plot3d (real(L33.x), real(L33.y), real(L33.z), ...
L33.x.n, L33.y.n, 3, 0);
}
_plflush ();
_pltext ();
#
# Increment the plot no. so that next time
# we use the correct settings.
#
WIN.[P].subplot = WIN.[P].subplot + 1;
return P;
};
##############################################################################
#
# Plot a Histogram(s), from the columns of a matrix.
#
##############################################################################
plhist = function ( M , nbin )
{
local (i, k, np, p)
check_plot_object ();
if (!exist (nbin)) { nbin = 10; }
p = mod (WIN.[P].subplot, WIN.[P].nplot) + 1; # The current index
np = M.nr;
# Compute max/min values of data
ymin = min (real (M));
ymax = max (real (M));
#
# Check computed scale limits against user's
#
if (!isinf (WIN.[P].ymin[p])) { ymin = WIN.[P].ymin[p]; }
if (!isinf (WIN.[P].ymax[p])) { ymax = WIN.[P].ymax[p]; }
_plgra ();
_plcol (1);
_plfont (WIN.[P].font[p]);
_plwid (WIN.[P].width[p]);
for (i in 1:M.nc)
{
hscale[i] = hist_scales (M[;i], nbin);
}
_pladv (0);
_plvsta ();
_plwind (ymin, ymax, 0, max (hscale));
_plbox (WIN.[P].gridx[p], 0, 0, WIN.[P].gridy[p], 0, 0);
for (i in 1:M.nc)
{
k = mod (i, 14) + 1;
_plcol (WIN.[P].color[p;k]);
_plhist (np, real(M[;i]), ymin, ymax, nbin, 1);
}
_plcol (1);
_pllab (WIN.[P].xlabel[p], WIN.[P].ylabel[p], WIN.[P].title[p]);
_plflush ();
_pltext ();
#
# Increment the plot no. so that next time
# we use the correct settings.
#
WIN.[P].subplot = WIN.[P].subplot + 1;
return 1;
};
##############################################################################
#
# Various support functions for the WIN list
#
##############################################################################
#
# Replot
#
replot = function ( )
{
check_plot_object ();
_replot ();
};
#
# Set the X-axis label
#
xlabel = function ( xstr )
{
local (i);
check_plot_object ();
if (!exist (xstr)) { xstr = ""; }
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
WIN.[P].xlabel[i] = xstr;
};
#
# Set the Y-axis label
#
ylabel = function ( xstr )
{
local (i);
check_plot_object ();
if (!exist (xstr)) { xstr = ""; }
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
WIN.[P].ylabel[i] = xstr;
};
#
# Set the Z-axis label
#
zlabel = function ( xstr )
{
local (i);
check_plot_object ();
if (!exist (xstr)) { xstr = ""; }
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
WIN.[P].zlabel[i] = xstr;
};
#
# Set the plot-title
#
ptitle = function ( xstr )
{
local (i);
check_plot_object ();
if (!exist (xstr)) { xstr = ""; }
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
WIN.[P].title[i] = xstr;
};
plimits = function ( xmin, xmax, ymin, ymax, zmin, zmax )
{
local (i);
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (xmin)) {
WIN.[P].xmin[i] = xmin;
else
WIN.[P].xmin[i] = inf ();
}
if (exist (xmax)) {
WIN.[P].xmax[i] = xmax;
else
WIN.[P].xmax[i] = inf ();
}
if (exist (ymin)) {
WIN.[P].ymin[i] = ymin;
else
WIN.[P].ymin[i] = inf ();
}
if (exist (ymax)) {
WIN.[P].ymax[i] = ymax;
else
WIN.[P].ymax[i] = inf ();
}
if (exist (zmin)) {
WIN.[P].zmin[i] = zmin;
else
WIN.[P].zmin[i] = inf ();
}
if (exist (zmax)) {
WIN.[P].zmax[i] = zmax;
else
WIN.[P].zmax[i] = inf ();
}
};
plgrid = function ( sty_x, sty_y )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (sty_x))
{
if (class (sty_x) == "string")
{
WIN.[P].gridx[i] = sty_x;
else
error ("plgrid: requires string argument GRID_STY_X");
}
else
WIN.[P].gridx[i] = grid_x_default;
}
if (exist (sty_y))
{
if (class (sty_y) == "string")
{
WIN.[P].gridy[i] = sty_y;
else
error ("plgrid: requires string argument GRID_STY_Y");
}
else
WIN.[P].gridy[i] = grid_y_default;
}
};
plgrid3 = function ( sty_x, sty_y, sty_z )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (sty_x))
{
if (class (sty_x) == "string")
{
WIN.[P].grid3x[i] = sty_x;
else
error ("plgrid3: requires string argument GRID_STY_X");
}
else
WIN.[P].grid3x[i] = grid_3x_default;
}
if (exist (sty_y))
{
if (class (sty_y) == "string")
{
WIN.[P].grid3y[i] = sty_y;
else
error ("plgrid3: requires string argument GRID_STY_Y");
}
else
WIN.[P].grid3y[i] = grid_3y_default;
}
if (exist (sty_z))
{
if (class (sty_z) == "string")
{
WIN.[P].grid3z[i] = sty_z;
else
error ("plgrid3: requires string argument GRID_STY_Z");
}
else
WIN.[P].grid3z[i] = grid_3z_default;
}
};
#
# A friendlier interface to changing grid/axis
# styles.
#
plaxis = function ( X_STR, Y_STR )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (X_STR))
{
if (X_STR == "log") { WIN.[P].gridx[i] = "bcngstl"; }
else
WIN.[P].gridx[i] = grid_x_default;
}
if (exist (Y_STR))
{
if (Y_STR == "log") { WIN.[P].gridy[i] = "bcngstlv"; }
else
WIN.[P].gridy[i] = grid_y_default;
}
return P;
};
#
# Change plot aspect ratio
#
plaspect = function ( style )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (style)) { WIN.[P].aspect[i] = style; }
};
#
# Change plot line style
#
plstyle = function ( style )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (style)) {
if (class (style) == "string")
{
if (style == "line") {
WIN.[P].style[i] = "line";
else if (style == "point") {
WIN.[P].style[i] = "point";
else if (style == "line-point") {
WIN.[P].style[i] = "line-point";
}}}
}
return 1;
}
WIN.[P].style[i] = "line";
};
#
# Change fonts
#
plfont = function ( font )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (!exist (font)) { font = 1; }
if (WIN.[P].fontld == 0)
{
_plfontld (1);
WIN.[P].fontld = 1;
}
WIN.[P].font[i] = font;
return P;
};
#
# Change pen width
#
plwid = function ( width )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (!exist (width)) { width = 1; }
WIN.[P].width[i] = width;
return P;
};
#
# Place some text on the plot
#
plptex = function ( text, x , y , dx , dy , just )
{
if (!check_plot_object ()) {
printf ("Must use plot() before plptex()\n");
return 0;
}
if (!exist (x)) { x = 0; }
if (!exist (y)) { y = 0; }
if (!exist (dx)) { dx = x+1; }
if (!exist (dy)) { dy = 0; }
if (!exist (just)) { just = 0; }
_plptex (x, y, dx, dy, just, text);
};
#
# Set up the viewing altitude for 3-D plots
#
plalt = function ( ALT )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (ALT))
{
WIN.[P].alt[i] = ALT;
else
WIN.[P].alt[i] = 60;
}
return P;
};
#
# Set the viewing azimuth for 3-D plots
#
plaz = function ( AZ )
{
local (i)
check_plot_object ();
i = mod (WIN.[P].subplot, WIN.[P].nplot) + 1;
if (exist (AZ))
{
WIN.[P].az[i] = AZ;
else
WIN.[P].az[i] = 45;
}
return P;
};
##############################################################################
#
# Various internal support functions. Eventually these will be static.
#
##############################################################################
#
# Find the X and Y scales for a single matrix.
#
xy_scales = function ( M, p, xmin, xmax, ymin, ymax )
{
#
# 1st check for un-plottable data
#
if (any (any (isinf (M))))
{ error ("plot: cannot plot infs"); }
if (any (any (isnan (M))))
{ error ("plot: cannot plot NaNs"); }
if (M.nc == 1)
{
xmin = 1;
xmax = M.nr;
ymin = min (M);
ymax = max (M);
else
xmin = min (M[;1]);
xmax = max (M[;1]);
ymin = min (min (M[;2:M.nc]));
ymax = max (max (M[;2:M.nc]));
}
#
# Check computed scale limits against user's
#
if (!isinf (WIN.[P].xmin[p])) { xmin = WIN.[P].xmin[p]; }
if (!isinf (WIN.[P].xmax[p])) { xmax = WIN.[P].xmax[p]; }
if (!isinf (WIN.[P].ymin[p])) { ymin = WIN.[P].ymin[p]; }
if (!isinf (WIN.[P].ymax[p])) { ymax = WIN.[P].ymax[p]; }
#
# Check for potential errors
#
if (xmin == xmax)
{
xmin = xmin - 1;
xmax = xmax + 1;
}
if (ymin == ymax)
{
ymin = ymin - 1;
ymax = ymax + 1;
}
#
# Finally, adjust if log-scales
#
if (find_char (WIN.[P].gridx[p], "l"))
{
if (xmin <= 0 || xmax <= 0) { error ("plot: cannot plot log <= 0"); }
xmin = log10 (xmin);
xmax = log10 (xmax);
}
if (find_char (WIN.[P].gridy[p], "l"))
{
if (ymin <= 0 || ymax <= 0) { error ("plot: cannot plot log <= 0"); }
ymin = log10 (ymin);
ymax = log10 (ymax);
}
return 1;
};
#
# Find the X, Y and Z scales for a single matrix.
#
xyz_scales = function ( L, p, xmin, xmax, ymin, ymax, zmin, zmax )
{
# X - scale
if (any (any (isinf (L.x))))
{ error ("plot3: cannot plot infs"); }
if (any (any (isnan (L.x))))
{ error ("plot3: cannot plot NaNs"); }
xmin = min (real (L.x));
xmax = max (real (L.x));
# Y - scale
if (any (any (isinf (L.y))))
{ error ("plot3: cannot plot infs"); }
if (any (any (isnan (L.y))))
{ error ("plot3: cannot plot NaNs"); }
ymin = min (real (L.y));
ymax = max (real (L.y));
# Z - scale
if (any (any (isinf (L.z))))
{ error ("plot3: cannot plot infs"); }
if (any (any (isnan (L.z))))
{ error ("plot3: cannot plot NaNs"); }
zmin = min (min (real (L.z)));
zmax = max (max (real (L.z)));
#
# Check computed scale limits against user's
#
if (!isinf (WIN.[P].xmin[p])) { xmin = WIN.[P].xmin[p]; }
if (!isinf (WIN.[P].xmax[p])) { xmax = WIN.[P].xmax[p]; }
if (!isinf (WIN.[P].ymin[p])) { ymin = WIN.[P].ymin[p]; }
if (!isinf (WIN.[P].ymax[p])) { ymax = WIN.[P].ymax[p]; }
if (!isinf (WIN.[P].zmin[p])) { zmin = WIN.[P].zmin[p]; }
if (!isinf (WIN.[P].zmax[p])) { zmax = WIN.[P].zmax[p]; }
return 1;
};
#
# Find the X and Y scales for a list of matrices
#
list_scales = function ( data, p, Xmin, Xmax, Ymin, Ymax )
{
local (M, i, xmin, xmax, ymin, ymax, once)
once = 1;
for (i in members (data))
{
M = real (data.[i]);
if (class (M) != "num") { continue; }
#
# 1st check for un-plottable data
#
if (any (any (isinf (M))))
{ error ("plot: cannot plot infs"); }
if (any (any (isnan (M))))
{ error ("plot: cannot plot NaNs"); }
if (M.nc == 1)
{
xmin = 1;
xmax = M.nr;
ymin = min (M);
ymax = max (M);
else
xmin = min (M[;1]);
xmax = max (M[;1]);
ymin = min (min (M[;2:M.nc]));
ymax = max (max (M[;2:M.nc]));
}
if (once) {
Xmin = xmin; Xmax = xmax; Ymin = ymin; Ymax = ymax;
once = 0;
}
if (xmin < Xmin) { Xmin = xmin; }
if (xmax > Xmax) { Xmax = xmax; }
if (ymin < Ymin) { Ymin = ymin; }
if (ymax > Ymax) { Ymax = ymax; }
}
#
# Check computed scale limits against user's
#
if (!isinf (WIN.[P].xmin[p])) { Xmin = WIN.[P].xmin[p]; }
if (!isinf (WIN.[P].xmax[p])) { Xmax = WIN.[P].xmax[p]; }
if (!isinf (WIN.[P].ymin[p])) { Ymin = WIN.[P].ymin[p]; }
if (!isinf (WIN.[P].ymax[p])) { Ymax = WIN.[P].ymax[p]; }
#
# Finally, adjust if log-scales
#
if (find_char (WIN.[P].gridx[p], "l"))
{
if (Xmin <= 0 || Xmax <= 0) { error ("plot: cannot plot log x <= 0"); }
Xmin = log10 (Xmin);
Xmax = log10 (Xmax);
}
if (find_char (WIN.[P].gridy[p], "l"))
{
if (Ymin <= 0 || Ymax <= 0) { error ("plot: cannot plot log y <= 0"); }
Ymin = log10 (Ymin);
Ymax = log10 (Ymax);
}
return 1;
};
#
# Find the maximum number of elements in a bin for a single
# column matrix.
#
hist_scales = function ( data, nbin )
{
local (i, binval, dmin, dmax, dbin)
dmin = min (real (data));
dmax = max (real (data));
dbin = linspace (dmin, dmax, nbin+1);
binval = zeros (nbin, 1);
for (i in 1:nbin)
{
binval[i] = length (find (data >= dbin[i] && data < dbin[i+1]));
}
return max (binval);
};
#
# Plot the columns of a matrix (core function)
#
plot_matrix = function ( M, p, K )
{
local (ans, i, k, l, np, x, y)
np = M.nr;
if (M.nc == 1)
{
x = 1:M.nr;
y = real (M);
k = mod (1+K, 14) + 1;
l = mod (1+K, 8) + 1;
if (find_char (WIN.[P].gridx[p], "l"))
{ x = log10 (x); }
if (find_char (WIN.[P].gridy[p], "l"))
{ y = log10 (y); }
_plcol (WIN.[P].color[p;k]);
_pllsty (WIN.[P].lstyle[p;l]);
if (WIN.[P].style[p] == "line") {
_plline (M.nr, x, y);
else if (WIN.[P].style[p] == "point") {
_plpoin (M.nr, x, y, WIN.[P].pstyle[p]+k);
else if (WIN.[P].style[p] == "line-point") {
_plline (M.nr, x, y);
_plpoin (M.nr, x, y, WIN.[P].pstyle[p]+k);
}}}
else
#
# Check for large column dimension
#
if (M.nc > M.nr)
{
printf (" Plot %i columns and %i rows, are you sure (y/n) ? "...
, M.nc, M.nr);
ans = getline ("stdin");
if (ans.[1] != "y") { return -1; }
}
for (i in 2:M.nc)
{
x = real (M[;1]);
y = real (M[;i]);
if (find_char (WIN.[P].gridx[p], "l"))
{ x = log10 (x); }
if (find_char (WIN.[P].gridy[p], "l"))
{ y = log10 (y); }
k = mod (i-1 + K, 14) + 1;
l = mod (i-1 + K, 8) + 1;
_plcol (WIN.[P].color[p;k]);
_pllsty (WIN.[P].lstyle[p;l]);
if (WIN.[P].style[p] == "line") {
_plline (np, x, y);
else if (WIN.[P].style[p] == "point") {
_plpoin (np, x, y, WIN.[P].pstyle[p]+k);
else if (WIN.[P].style[p] == "line-point") {
_plline (np, x, y);
_plpoin (np, x, y, WIN.[P].pstyle[p]+k);
}}}
}
}
return k;
};
#
# Plot all of the matrices in a list on the same plot
#
plot_list = function ( L , p )
{
local (M, i, k)
k = 0;
for (i in members (L))
{
M = L.[i];
if (class (M) != "num") { continue; }
if ((k = plot_matrix (M, p, k)) < 0) { return k; }
}
return 1;
};
#
# Check the elements of LIST.
# LIST must contain elements `x', `y',
# and `z'
#
check_3d_list = function ( LIST )
{
#
# Check existence and types
#
if (class (LIST) != "list") {
error ("plot3: argument must be a list");
}
if (!exist (LIST.x)) {
error ("plot3: arg must contain `x' member");
else if (class (LIST.x) != "num") {
error ("plot3: x must be numeric");
}}
if (!exist (LIST.y)) {
error ("plot3: arg must contain `y' member");
else if (class (LIST.y) != "num") {
error ("plot3: y must be numeric");
}}
if (!exist (LIST.z)) {
error ("plot3: arg must contain `z' member");
else if (class (LIST.z) != "num") {
error ("plot3: z must be numeric");
}}
#
# Check sizes
#
if (LIST.x.n != LIST.z.nr) {
error ("plot3: x.n != z.nr");
}
if (LIST.y.n != LIST.z.nc) {
error ("plot3: y.n != z.nc");
}
};
find_char = function ( str , char )
{
local (i, tmp)
tmp = strsplt (str);
for (i in 1:tmp.n)
{
if (tmp[i] == char)
{
return i;
}
}
return 0;
};